package com.example.test.fetch.parser;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.example.test.fetch.fetcher.Fetcher;
import com.example.test.fetch.params.FetchParams;
import com.example.test.fetch.result.Ali1688OrderResult;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 阿里1688 订单页面解析器
 */
public class Ali1688OrderPageParser extends BaseParser<Ali1688OrderResult> {

    @Override
    public List<Ali1688OrderResult> parse(String responseBody) {


        // 2. 使用jsoup解析html
        Document document = Jsoup.parse(responseBody);
        // 订单列表
        Elements ordersElements = document.getElementsByClass("order-item");

        return ordersElements.stream().map(orderElement -> {
            // 订单标题元素
            Element orderTitleElement = orderElement.getElementsByClass("order-title").get(0);
            Element orderTableElement = orderElement.getElementsByClass("order-info").get(0);
            // 获取订单号、订单时间
            String orderNo = orderTitleElement.getElementsByClass("order-id").stream().findFirst()
                    .map(element -> element.text().trim())
                    .orElse(null);
            String orderTime = orderTitleElement.getElementsByClass("date").stream().findFirst()
                    .map(element -> element.text().trim())
                    .orElse(null);
            String merchantName = orderTitleElement.getElementsByClass("bannerCorp").stream().findFirst()
                    .map(element -> element.text().trim())
                    .orElse(null);
            // 获取订单划线金额、订单金额、订单状态
            String orderLinePrice = orderTableElement.getElementsByClass("sum-payment-original").stream().findFirst()
                    .map(element -> element.text().trim())  //
                    .orElse("-1");
            String orderPrice = orderTableElement.getElementsByClass("total").stream().findFirst()  //
                    .map(element -> element.text().trim())  //
                    .orElse("-1");
            String orderStatus = orderTableElement.getElementsByClass("s7").stream().findFirst()
                    .map(element -> element.getElementsByTag("div").stream().findFirst()
                            .map(element1 -> element1.text().trim())
                            .orElse(null)
                    )
                    .orElse(null);
            // 获取订单商品信息
            List<Ali1688OrderResult.OrderProductInfo> productInfoList = orderTableElement.getElementsByClass("detail").stream().findFirst()
                    .map(productElement -> productElement.getElementsByTag("table").first()   //
                            .getElementsByTag("tr").stream()
                            .map(orderProductElement -> {
                                String productName = orderProductElement.getElementsByClass("s2").get(0).getElementsByClass("productName").first().text();
                                String specInfo = orderProductElement.getElementsByClass("s2").get(0).getElementsByClass("trade-spec").first().text().trim();
                                String guaranteeInfo = orderProductElement.getElementsByClass("s2").get(0).getElementsByClass("support-icon").first().text().trim();
                                String price = orderProductElement.getElementsByClass("s3").get(0)
                                        .getElementsByAttribute("data-unit-price").first().text().trim();
                                String num = orderProductElement.getElementsByClass("s4").get(0).getElementsByTag("div").first().text().trim();
                                String deliveryStatus = orderProductElement.getElementsByClass("s9").get(0).text().trim();
                                String refundStatus = orderProductElement.getElementsByClass("s9").get(0).getElementsByTag("div").first().text().trim();


                                Ali1688OrderResult.OrderProductInfo productInfo = new Ali1688OrderResult.OrderProductInfo();
                                productInfo.setProductName(productName);
                                productInfo.setSpecInfo(
                                        StrUtil.split(specInfo, ";").stream()
                                                .map(StrUtil::trim)
                                                .map(str -> StrUtil.split(str, ":").stream().map(StrUtil::trim).collect(Collectors.toList()))
                                                .collect(Collectors.toMap(
                                                        item -> item.get(0),
                                                        item -> item.get(1)
                                                ))
                                );
                                productInfo.setPrice(new BigDecimal(price));
                                productInfo.setNum(Integer.valueOf(num));
                                productInfo.setGuaranteeInfo(
                                        StrUtil.split(guaranteeInfo, " ").stream()
                                                .map(StrUtil::trim)
                                                .collect(Collectors.toList())
                                );
                                productInfo.setDeliveryStatus(deliveryStatus);
                                productInfo.setRefundStatus(refundStatus);

//                                    System.out.println("\t"+ productName + " " + specInfo + " " + guaranteeInfo + " " + price + " " + num + " " + deliveryStatus + " " + refundStatus);
                                return productInfo;
                            }).collect(Collectors.toList()))
                    .orElse(ListUtil.empty());

            Ali1688OrderResult ali1688OrderResult = new Ali1688OrderResult();
            ali1688OrderResult.setOrderNo(orderNo);
            ali1688OrderResult.setOrderTime(orderTime);
            ali1688OrderResult.setStatus(orderStatus);
            ali1688OrderResult.setLinePrice(new BigDecimal(orderLinePrice));
            ali1688OrderResult.setPrice(new BigDecimal(orderPrice));
            ali1688OrderResult.setMerchantName(merchantName);
            ali1688OrderResult.setProductInfos(productInfoList);
            return ali1688OrderResult;
        }).collect(Collectors.toList());
    }

    @Override
    public boolean hasNext(String responseBody) {
        Document document = Jsoup.parse(responseBody);

        Element pagePanelEle = document.getElementsByClass("pagination-panel").get(0);
        int current = Integer.parseInt(pagePanelEle.getElementsByClass("current").get(0).text().trim());
        int total = Integer.parseInt(pagePanelEle.getElementsByClass("pages-total").get(0).text().trim());

        return current < total;
    }

    @Override
    public void check(int responseStatus, String responseBody) {
//        System.out.println("responseStatus: " + responseStatus);
//        System.out.println("responseBody: " + responseBody);
    }

    public static void main(String[] args) {
        String url = "https://trade.1688.com/order/buyer_order_list.htm" +
                " ?spm=a360q.8274423.0.0.49c84c9aQYZyep&scene_type=&source=&purchase_company_name=null&product_name=&start_date=&end_date=" +
                " &seller_login_id=&trade_status=&trade_type_search=&biz_type_search=&order_id_search=&is_his=&is_hidden_canceled_offer=" +
                " &apt=&related_code=&order_settle_flag=&company_name=&keywords=&receiver_tel=&receiver_name=&buyer_name=&down_stream_order_id=" +
                " &batch_number=&total_fee=&page_size=30";
        String cookies = "taklid=13c546f87d9d475f9216044df1ec21e2; cookie2=28b3b02425ba2ec49be31b9cedfe9b0a; t=724e1a7e84a89c04048fd04196145e9c; _tb_token_=e3153e3300b7e; __last_loginid__=b2b-2397664778; __last_memberid__=b2b-2397664778; lid=%E6%98%8C%E7%9B%9B%E4%BA%BF%E5%95%86%E8%B4%B8; __cn_logon__=true; __cn_logon_id__=%E6%98%8C%E7%9B%9B%E4%BA%BF%E5%95%86%E8%B4%B8; ali_apache_track=c_mid=b2b-2217702924013921c9|c_lid=%E6%98%8C%E7%9B%9B%E4%BA%BF%E5%95%86%E8%B4%B8|c_ms=1|c_mt=2; ali_apache_tracktmp=c_w_signed=Y; __mwb_logon_id__=%25E6%2598%258C%25E7%259B%259B%25E4%25BA%25BF%25E5%2595%2586%25E8%25B4%25B8; mwb=ng; firstRefresh=1719757090814; aliwwLastRefresh=1719757090850; is_identity=buyer; lastRefresh=1719788157473; mtop_partitioned_detect=1; _m_h5_tk=c223e9b19802c04983a7273deccdd33f_1720109557803; _m_h5_tk_enc=cec1d70bee4a1080817e01a9f9755620; cookie1=BqtUArpdeKcPR9aWB2RItcVS%2BoJn8ZGyA8S4WHUn5ns%3D; cookie17=UUpgQcUf5uN6kPZ9pA%3D%3D; sgcookie=E100UZR9m9o6m7kt4FoM3fjaReM5%2FxgaiX9tXMoJoaodf3y7GPyszWzreNgsIpP%2BqZpbGv0sQ3o1AkJVvVydzjUZOs%2BYS0ZsalHyo%2By9x3HhwOE%3D; sg=%E8%B4%B839; csg=1bb51d92; unb=2217702924013; uc4=id4=0%40U2gqztyI%2BJVwzCdkNOx1kxDI6Dt0rA4q&nk4=0%400wepfHXgTuKSYWkMBcdapjrKZLE0; _nk_=%5Cu660C%5Cu76DB%5Cu4EBF%5Cu5546%5Cu8D38; last_mid=b2b-2217702924013921c9; _csrf_token=1720102942241; xlly_s=1; JSESSIONID=D87B9BB062335B4CC4F40938E4359762; tfstk=f5gtwfVG-BCT_FKm5ftnimwcQ1Rn6VhwJAl5o-2GcvHKNvP0SjZ1A6NaKV2isP1xHvD8C-xZSZHKIv0mjZcfMSM35oognR2YkjkJtLYkrflauPJkEUfm_H1Qu-T0luHd0haXELYhiEr1urim2z18JXwUMSsf5x6CdJPPhrw_c9GQGJwblrMbAyNz6G1_CS6COUyF8--bEZnYgl1m9KeFlZg6ule-Tibfl2FTXYh_pXcnJ5ETFkvBBFg-NfgzMqR5D-hrfAVEHUpLRVHt5kUvkwziwDMTvcpAJkoIaqZKYLIrafMtVug6JBqK7b4_pqRVuRiiGqqx5L10CVkiJuuVBp2mqX0_vY9hJxrxf0askLLC49uoyy0GE8FcfBdd0ir_t0bNqD4uhWeu98AnCiS4vgPLEBKN0ir_TWektTIV0kIP.; isg=BDAwYTKGIrVW0_63By9xR-nsAfiCeRTDXbADTyqB-wte5dCP0ovEUpvTPe2F0Myb";


        FetchParams params = new FetchParams();
        params.setUrl(url);
        params.setParams(MapUtil.ofEntries());
        params.setCookies(parseCookiesToMap(cookies));
        params.setPageNumKey("page");
        params.setTimeout(10000);
        params.setRetryCount(3);

        Ali1688OrderPageParser parser = new Ali1688OrderPageParser();
        Fetcher<Ali1688OrderResult> fetcher = new Fetcher<>(params, parser);
        fetcher.start();
        List<Ali1688OrderResult> result = fetcher.getResult();
        System.out.println(JSONUtil.toJsonStr(result));
    }

    private static Map<String, String> parseCookiesToMap(String cookies) {
        return StrUtil.split(cookies, ";").stream()
                .map(StrUtil::trim)
                .map(str -> {
                    int idx = StrUtil.indexOf(str, '=');
                    String key = str.substring(0, idx);
                    String value = str.substring(idx + 1);

                    return new String[] { key, value };
                }).collect(Collectors.toMap(arr -> arr[0], arr -> arr[1]));
    }
}
